package com.newshub.logging.implementation.file;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.newshub.logging.core.LogStorage;
import com.newshub.logging.context.LogContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 文件日志存储实现
 */
@Slf4j
@Component
public class FileLogStorage implements LogStorage {
    
    @Value("${logging.storage.file.path:logs}")
    private String logPath;
    
    @Value("${logging.storage.file.prefix:news-hub}")
    private String logPrefix;
    
    @Value("${logging.storage.file.max-size:100MB}")
    private String maxSize;
    
    @Value("${logging.storage.file.max-count:10}")
    private int maxCount;
    
    private final ObjectMapper objectMapper = new ObjectMapper();
    private final Map<String, ReentrantLock> fileLocks = new ConcurrentHashMap<>();
    private final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    
    @Override
    public void store(LogContext context, String message, String level) {
        try {
            // 创建日志目录
            createLogDirectory();
            
            // 生成日志文件名
            String fileName = generateLogFileName();
            
            // 构建日志记录
            Map<String, Object> logRecord = buildLogRecord(context, message, level);
            
            // 写入日志文件
            writeLogToFile(fileName, logRecord);
            
        } catch (Exception e) {
            log.error("写入日志文件失败", e);
        }
    }
    
    @Override
    public List<Map<String, Object>> query(String module, String level, 
                                          String startTime, String endTime, 
                                          String keyword, int page, int size) {
        // TODO: 实现日志查询功能
        return new ArrayList<>();
    }
    
    @Override
    public Map<String, Object> getStatistics(String module, String level, 
                                            String startTime, String endTime) {
        // TODO: 实现日志统计功能
        return new HashMap<>();
    }
    
    @Override
    public void deleteExpiredLogs(String beforeTime) {
        // TODO: 实现过期日志删除功能
    }
    
    @Override
    public byte[] exportLogs(String module, String level, 
                           String startTime, String endTime, 
                           String format) {
        // TODO: 实现日志导出功能
        return new byte[0];
    }
    
    private void createLogDirectory() throws IOException {
        Path path = Paths.get(logPath);
        if (!Files.exists(path)) {
            Files.createDirectories(path);
        }
    }
    
    private String generateLogFileName() {
        String today = LocalDateTime.now().format(dateFormatter);
        return String.format("%s/%s-%s.log", logPath, logPrefix, today);
    }
    
    private Map<String, Object> buildLogRecord(LogContext context, String message, String level) {
        Map<String, Object> record = new HashMap<>();
        record.put("timestamp", LocalDateTime.now().toString());
        record.put("level", level);
        record.put("message", message);
        record.put("module", context.getModule());
        record.put("description", context.getDescription());
        record.put("methodName", context.getMethodName());
        record.put("className", context.getClassName());
        record.put("threadId", context.getThreadId());
        record.put("threadName", context.getThreadName());
        record.put("requestId", context.getRequestId());
        record.put("userId", context.getUserId());
        record.put("username", context.getUsername());
        record.put("ipAddress", context.getIpAddress());
        record.put("requestUrl", context.getRequestUrl());
        record.put("executionTime", context.getExecutionTime());
        
        if (context.getException() != null) {
            record.put("exception", context.getException().getMessage());
            record.put("exceptionType", context.getException().getClass().getSimpleName());
        }
        
        if (context.getMetadata() != null) {
            record.put("metadata", context.getMetadata());
        }
        
        return record;
    }
    
    private void writeLogToFile(String fileName, Map<String, Object> logRecord) throws IOException {
        ReentrantLock lock = fileLocks.computeIfAbsent(fileName, k -> new ReentrantLock());
        lock.lock();
        try {
            String logLine = objectMapper.writeValueAsString(logRecord) + "\n";
            try (FileWriter writer = new FileWriter(fileName, true)) {
                writer.write(logLine);
                writer.flush();
            }
        } finally {
            lock.unlock();
        }
    }
}
